/**
 * @author Apocrypha
 * 
 * Persistence in computer science refers to the characteristic of state that outlives the process that created it. Without this capability, state would only exist in RAM, and would be lost when this RAM loses power, such as a computer shutdown.[citation needed]
 * This is achieved in practice by storing the state as data in non-volatile storage such as a hard drive or flash memory.
 * Picture editing programs or word processors, for example, achieve state persistence by saving their documents to files.
 */
package ganga.custodian.persistence;

import ganga.custodian.human.PhysicalActivityMode;
import ganga.custodian.sensors.AccelerometerData;

import android.content.ContentValues;
import android.content.Context;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;

import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.Locale;

public class Database extends SQLiteOpenHelper {

	//private static final String DATABASE_NAME = "/sdcard/Custodian.sqlite";
	private static final String DATABASE_NAME = "Custodian.sqlite";
	private static final int    DATABASE_VERSION = 12;
	@SuppressWarnings("unused")
	private final Context context;
	// Полный формат String dateTimeFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS";
	String dateTimeFormat = "HH:mm:ss.SSS";
	SimpleDateFormat sdf = new SimpleDateFormat(dateTimeFormat, Locale.US);
	
	public Database(Context context) {
		super(context, DATABASE_NAME, null, DATABASE_VERSION);
		this.context = context;
	}

	@Override
	public void onCreate(SQLiteDatabase db) {
		String sessionSql = "CREATE TABLE Session (SessionId INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL UNIQUE, StartDateTime DATETIME,Position TEXT,Activity TEXT,Movement TEXT,HumanId INTEGER,DeviceId INTEGER,Duration BIGINT);";
		String accelerationSql = "CREATE TABLE Acceleration(SessionId INTEGER, DateTimeStamp TEXT, EventTimeStamp TEXT, X FLOAT, Y FLOAT, Z FLOAT)";
		String locationSql = "CREATE TABLE Location(SessionId INTEGER, DateTimeStamp TEXT, Long FLOAT, Lat FLOAT)";
		db.beginTransaction();
		try {
			db.execSQL(sessionSql);
			db.execSQL(accelerationSql);
			db.execSQL(locationSql);
			db.setTransactionSuccessful();
			Log.d(DATABASE_NAME, "Ok");
		} catch (SQLException ex) {
			Log.e("Unable to create Custodian database", ex.toString());
			throw ex;
		} finally{
			db.endTransaction();
		}
	}

	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
		// TODO Пока не реализовано
	}
	/**
	 * Создание новой измерительной сессии версия с перечислением
	 * @param startDateTime
	 * @param calibrationMode
	 * @param calibrationModeDetail 
	 * @return TODO
	 * @deprecated
	 */
	public long insertMeasurementSession(Timestamp startDateTime,
			PhysicalActivityMode calibrationMode, String calibrationModeDetail) {
		long result = 0;
		try {
			ContentValues values = new ContentValues();
			values.put("StartDateTime", startDateTime.toGMTString());
			values.put("CalibrationMode", calibrationMode.toString());
			values.put("CalibrationModeDetail", calibrationModeDetail);
			values.put("HumanId", 2);//1-GIB //
			result = getWritableDatabase().insert("Session", null, values);
			if (result == -1)
				Log.e(DATABASE_NAME, "Insert fail");
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		return result;
	}
	/**
	 * Создание новой измерительной сессии версия со строками
	 * @param startDateTime
	 * @param position
	 * @param activity
	 * @param movement
	 * @return
	 */
	public long insertMeasurementSession(Timestamp startDateTime,
			String position, String activity, String movement) {
		long result = 0;
		try {
			ContentValues values = new ContentValues();
			values.put("StartDateTime", startDateTime.toGMTString());
			values.put("Position", position);
			values.put("Activity", activity);
			values.put("Movement", movement);
			values.put("HumanId", 2);//1-GIB, 2-Juko //3-Cuarto
			values.put("DeviceId", 2);//1-HTC //2-Samsung //
			result = getWritableDatabase().insert("Session", null, values);
			if (result == -1)
				Log.e(DATABASE_NAME, "Insert fail");
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		return result;
	}
	public void updateMeasurementSession(long sessionId, long duration){
		try {
			ContentValues values = new ContentValues();
			values.put("Duration", duration);
			String[] whereArgs = new String[]{Long.toString(sessionId)};
			getWritableDatabase().update("Session", values, "SessionId=?", whereArgs);
		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}
	public void insertAcc(long sessionId, AccelerometerData data){
		try {
			ContentValues values = new ContentValues();
			values.put("SessionId", sessionId);
			//String stamp;
			//if (data.timestamp == null)
			//	stamp = "Null data";
			//else {
			//	stamp = sdf.format(data.timestamp);
			//}
			values.put("DateTimeStamp", data.timestamp);
			values.put("EventTimeStamp ", data.eventTimestamp);
			float x = (float)Math.round(data.ax*100) /100;
			values.put("X", x);
			values.put("Y", data.ay);
			values.put("Z", data.az);
			long result = getWritableDatabase().insert("Acceleration", null, values);
			if (result == -1)
				Log.e(DATABASE_NAME, "Insert Acc data fail");
		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}
}